package com.woke.method;

import android.app.Activity;
import android.app.Application;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.Environment;
import android.preference.PreferenceManager;
import android.support.multidex.MultiDex;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.Log;

import com.bilibili.boxing.BoxingCrop;
import com.bilibili.boxing.BoxingMediaLoader;
import com.bilibili.boxing.loader.IBoxingMediaLoader;
import com.boxing.BoxingGlideLoader;
import com.boxing.BoxingUcrop;
import com.example.woke.MainActivity;
import com.example.woke.SettingActivity;
import com.lzy.okgo.OkGo;
import com.lzy.okgo.cache.CacheEntity;
import com.lzy.okgo.cache.CacheMode;
import com.lzy.okgo.cookie.CookieJarImpl;
import com.lzy.okgo.cookie.store.DBCookieStore;
import com.lzy.okgo.https.HttpsUtils;
import com.lzy.okgo.interceptor.HttpLoggingInterceptor;
import com.lzy.okgo.model.HttpHeaders;
import com.lzy.okgo.model.HttpParams;
import com.netease.nim.uikit.api.NimUIKit;
import com.netease.nim.uikit.api.UIKitOptions;
import com.netease.nimlib.sdk.NIMClient;
import com.netease.nimlib.sdk.util.NIMUtil;
import com.tencent.bugly.Bugly;
import com.tencent.bugly.beta.Beta;
import com.woke.serizedatas.Datas_load;
import com.wokeMy.view.http.LogUtil;
import com.wokeMy.view.model.Constant;
import com.wokeMy.view.util.MyActivityManager;
import com.wokeMy.view.yunxing.NimDemoLocationProvider;
import com.zhongcai.online.BuildConfig;
import com.zhongcai.online.R;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.HashMap;
import java.util.HashSet;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLSession;
import javax.net.ssl.X509TrustManager;

import cn.jpush.android.api.JPushInterface;
import cn.sharesdk.framework.ShareSDK;
import cn.sharesdk.tencent.qq.QQ;
import cn.sharesdk.tencent.qzone.QZone;
import cn.sharesdk.wechat.favorite.WechatFavorite;
import cn.sharesdk.wechat.friends.Wechat;
import cn.sharesdk.wechat.moments.WechatMoments;
import cn.xl.xxl.tools.Tools;
import io.realm.Realm;
import io.realm.RealmConfiguration;
import okhttp3.OkHttpClient;

public class MyApp extends Application implements Application.ActivityLifecycleCallbacks {

	//	public String userid, user_id,regid,truename,paypsw,user_money,use_p,adress,mustpay,sericon,last_login_time;
	public String regid, mustpay,appName;
	private static final String TAG = "JPush";
	public static int screenWidth;
	public static int screenHigth;
	private static MyApp mInstance = null;
	//	public int phithd;
	public int tyep5 = 6;//�����;�ڼ��
	public String newicon;//
	//	public String user_nopic,user_nopic1,user_no,user_nicename;
	public boolean newchange;
	public Datas_load loaddata;
	public SharedPreferences sharep;

	private static Context context;

	@Override
	public void onCreate() {
		// TODO Auto-generated method stub
		super.onCreate ();
		// SDK初始化（启动后台服务，若已经存在用户登录信息， SDK 将完成自动登录）
		// ... your codes
		context=getApplicationContext();
		NIMClient.init(this, null,null);

		if (NIMUtil.isMainProcess(this)) {
			// 注意：以下操作必须在主进程中进行
			// 1、UI相关初始化操作
			// 2、相关Service调用
			// 初始化
			NimUIKit.init(this,buildUIKitOptions());
			NimUIKit.setLocationProvider(new NimDemoLocationProvider());
		}

		String processName = com.wokeMy.view.util.Util.getProcessName(this, android.os.Process.myPid());
		if(processName != null){
			boolean defaultProcess = processName.equals(this.getPackageName());
			appName=getResources().getString(R.string.oem_app_name);
			if(defaultProcess){
				//当前应用的初始化
				Log.e(":defaultProcess",this.getPackageName());
				mInstance = this;
				Tools.getInstance (this);

				//1.Realm  本地数据库
				Realm.init (this);
				RealmConfiguration config = new RealmConfiguration.Builder ().name ("a88china.realm")
						.deleteRealmIfMigrationNeeded ()
						.build ();
				Realm.setDefaultConfiguration (config);

				JPushInterface.setDebugMode(false);
				JPushInterface.init (this);   //极光推送 JPush
				DisplayMetrics dm = getResources ().getDisplayMetrics ();

				screenWidth = dm.widthPixels;
				screenHigth = dm.heightPixels;


				sharep = this.getSharedPreferences ("loaduser", Context.MODE_PRIVATE);
				com.woke.method.Httploaddata.uploadFile (this);
				initBilibiliBoxing ();
				initShare();
				initOkGo();
//				com.woke.method.Httploaddata.sysKguan (sharep,appName);
				// 初始化Looger工具
				LogUtil.init(BuildConfig.DEBUG);            // default PRETTYLOG

			}else if (processName.contains(":multiprocess")) {
				Log.e(":multiprocess",":multiprocess");
			}
			initBugly ();
			registerActivityLifecycleCallbacks(this);
		}


//		UpayTask.getInstance ()
//				.initUpay (false, true, "00000011001200200000100", "1001200200000100", "8501d1f1b8abc824487c8dd029d77639");

//		//4.内存溢出监控
//		if (LeakCanary.isInAnalyzerProcess (this)) {
//			return;
//		}
//		LeakCanary.install (this);
	}


	private UIKitOptions buildUIKitOptions() {
		UIKitOptions options = new UIKitOptions();
		// 设置app图片/音频/日志等缓存目录
		options.appCacheDir = getAppCacheDir(this) + "/app";
		return options;
	}
	public static Context getContext() {
		return context;
	}

	/**
	 * 配置 APP 保存图片/语音/文件/log等数据的目录
	 * 这里示例用SD卡的应用扩展存储目录
	 */
	static String getAppCacheDir(Context context) {
		String storageRootPath = null;
		try {
			// SD卡应用扩展存储区(APP卸载后，该目录下被清除，用户也可以在设置界面中手动清除)，请根据APP对数据缓存的重要性及生命周期来决定是否采用此缓存目录.
			// 该存储区在API 19以上不需要写权限，即可配置 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="18"/>
			if (context.getExternalCacheDir() != null) {
				storageRootPath = context.getExternalCacheDir().getCanonicalPath();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		if (TextUtils.isEmpty(storageRootPath)) {
			// SD卡应用公共存储区(APP卸载后，该目录不会被清除，下载安装APP后，缓存数据依然可以被加载。SDK默认使用此目录)，该存储区域需要写权限!
			storageRootPath = Environment.getExternalStorageDirectory() + "/" + getContext().getPackageName();
		}

		return storageRootPath;
	}
	/**
	 * 初始化Bilibili/boxing 图片选择
	 */
	private void initBilibiliBoxing() {
		IBoxingMediaLoader loader = new BoxingGlideLoader ();
		BoxingMediaLoader.getInstance ().init (loader);
		BoxingCrop.getInstance ().init (new BoxingUcrop ());
	}

	/**
	 * 初始化腾信 Bugly
	 */
	private void initBugly() {
		Beta.canShowUpgradeActs.add (MainActivity.class);
		Beta.canShowUpgradeActs.add (SettingActivity.class);
		Beta.tipsDialogLayoutId = R.layout.bugly_tips_dialog;
		Beta.upgradeDialogLayoutId = R.layout.bugly_upgrade_dialog;
		/**
		 * wifi下自动下载
		 */
		Beta.autoDownloadOnWifi = true;
		/**
		 * 是否显示弹窗apk信息（默认弹窗）
		 */
		Beta.canShowApkInfo = true;
		String value= Constant.CHECKUP_KEY.get(appName);
		Bugly.init (getApplicationContext (), value, false);

	}
	/**
	 * 初始化sharesdk
	 */
	private void initShare() {
		String sharesdk_key= Constant.SHARESDK_KEY.get(appName);
		String qq_appid= Constant.QQSHARE_APPID.get(appName);
		String qq_appsecret= Constant.QQSHARE_APPECRET.get(appName);
		String wx_appid= Constant.WXSHARE_APPID.get(appName);
		String wx_appsecret= Constant.WXSHARE_APPECRET.get(appName);
		ShareSDK.initSDK (this,sharesdk_key);
		HashMap<String,Object> hashMap = new HashMap<String, Object>();
		hashMap.put("Id","3");
		hashMap.put("SortId","3");
		hashMap.put("AppId",qq_appid);
		hashMap.put("AppSecret",qq_appsecret);
		hashMap.put("ShareByAppClient","true");
		hashMap.put("Enable","true");
		ShareSDK.setPlatformDevInfo(QZone.NAME,hashMap);

		hashMap.clear();
		hashMap.put("Id","4");
		hashMap.put("SortId","4");
		hashMap.put("AppId",wx_appid);
		hashMap.put("AppSecret",wx_appsecret);
		hashMap.put("ShareByAppClient","true");
		hashMap.put("Enable","true");
		hashMap.put("BypassApproval","false");
		ShareSDK.setPlatformDevInfo(Wechat.NAME,hashMap);

		hashMap.clear();
		hashMap.put("Id","5");
		hashMap.put("SortId","5");
		hashMap.put("AppId",wx_appid);
		hashMap.put("AppSecret",wx_appsecret);
		hashMap.put("ShareByAppClient","true");
		hashMap.put("Enable","true");
		hashMap.put("BypassApproval","false");
		ShareSDK.setPlatformDevInfo(WechatMoments.NAME,hashMap);

		hashMap.clear();
		hashMap.put("Id","6");
		hashMap.put("SortId","6");
		hashMap.put("AppId",wx_appid);
		hashMap.put("AppSecret",wx_appsecret);
		hashMap.put("ShareByAppClient","true");
		hashMap.put("Enable","true");
		hashMap.put("BypassApproval","false");
		ShareSDK.setPlatformDevInfo(WechatFavorite.NAME,hashMap);

		hashMap.clear();
		hashMap.put("Id","6");
		hashMap.put("SortId","6");
		hashMap.put("AppId",qq_appid);
		hashMap.put("AppSecret",qq_appsecret);
		hashMap.put("ShareByAppClient","true");
		hashMap.put("Enable","true");
		ShareSDK.setPlatformDevInfo(QQ.NAME,hashMap);

	}

	@Override
	protected void attachBaseContext(Context base) {
		super.attachBaseContext (base);
		MultiDex.install (this);
	}

	public int gettype5() {
		return tyep5;
	}

	public Datas_load getDatas_load() {
		return loaddata;
	}

	public void setDatas_load(Datas_load loaddata) {
		this.loaddata = loaddata;
	}

	public int settype5(int tyep5) {
		return this.tyep5 = tyep5;
	}

	public static MyApp getInstance() {
		return mInstance;
	}


	public String getregid() {
		return regid;
	}

	public String setregid(String regid) {
		return this.regid = regid;
	}


	public String gethavetopay() {
		return mustpay;
	}

	public String sethavetopay(String mustpay) {
		return this.mustpay = mustpay;
	}


	public boolean getNewchange() {
		return newchange;
	}

	public boolean setNewchange(boolean newchange) {
		return this.newchange = newchange;
	}

	public void setMerchantsType(Datas_load loaddata) {
		this.loaddata = loaddata;
	}

	public static MyApp newInstance() {
		return mInstance;
	}

	public void saveCookies(HashSet<String> cookies) {
		PreferenceManager.getDefaultSharedPreferences (this)
				.edit ()
				.putStringSet ("zc_cookies", cookies)
				.apply ();
	}

	public HashSet<String> readCookies() {
		return (HashSet<String>) PreferenceManager.getDefaultSharedPreferences (this)
				.getStringSet ("zc_cookies", new HashSet<String> ());
	}

	/**
	 * 获取进程号对应的进程名
	 *
	 * @param pid 进程号
	 * @return 进程名
	 */
	private static String getProcessName(int pid) {
		BufferedReader reader = null;
		try {
			reader = new BufferedReader (new FileReader ("/proc/" + pid + "/cmdline"));
			String processName = reader.readLine ();
			if (! TextUtils.isEmpty (processName)) {
				processName = processName.trim ();
			}
			return processName;
		} catch (Throwable throwable) {
			throwable.printStackTrace ();
		} finally {
			try {
				if (reader != null) {
					reader.close ();
				}
			} catch (IOException exception) {
				exception.printStackTrace ();
			}
		}
		return null;
	}

	@Override
	public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
		MyActivityManager.addActivity(activity);
	}

	@Override
	public void onActivityStarted(Activity activity) {

	}

	@Override
	public void onActivityResumed(Activity activity) {

	}

	@Override
	public void onActivityPaused(Activity activity) {

	}

	@Override
	public void onActivityStopped(Activity activity) {

	}

	@Override
	public void onActivitySaveInstanceState(Activity activity, Bundle outState) {

	}

	@Override
	public void onActivityDestroyed(Activity activity) {
		MyActivityManager.removeActivity(activity);
	}

	private void initOkGo() {
		//---------这里给出的是示例代码,告诉你可以这么传,实际使用的时候,根据需要传,不需要就不传-------------//
		HttpHeaders headers = new HttpHeaders();
		headers.put("commonHeaderKey1", "commonHeaderValue1");    //header不支持中文，不允许有特殊字符
		headers.put("commonHeaderKey2", "commonHeaderValue2");
		HttpParams params = new HttpParams();
		params.put("commonParamsKey1", "commonParamsValue1");     //param支持中文,直接传,不要自己编码
		params.put("commonParamsKey2", "这里支持中文参数");
		//----------------------------------------------------------------------------------------//

		OkHttpClient.Builder builder = new OkHttpClient.Builder();
		//log相关
		HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor("OkGo");
		loggingInterceptor.setPrintLevel(HttpLoggingInterceptor.Level.BODY);        //log打印级别，决定了log显示的详细程度
		loggingInterceptor.setColorLevel(Level.INFO);                               //log颜色级别，决定了log在控制台显示的颜色
		builder.addInterceptor(loggingInterceptor);                                 //添加OkGo默认debug日志
		//第三方的开源库，使用通知显示当前请求的log，不过在做文件下载的时候，这个库好像有问题，对文件判断不准确
		//builder.addInterceptor(new ChuckInterceptor(this));

		//超时时间设置，默认60秒
		builder.readTimeout(OkGo.DEFAULT_MILLISECONDS, TimeUnit.MILLISECONDS);      //全局的读取超时时间
		builder.writeTimeout(OkGo.DEFAULT_MILLISECONDS, TimeUnit.MILLISECONDS);     //全局的写入超时时间
		builder.connectTimeout(OkGo.DEFAULT_MILLISECONDS, TimeUnit.MILLISECONDS);   //全局的连接超时时间

		//自动管理cookie（或者叫session的保持），以下几种任选其一就行
		//builder.cookieJar(new CookieJarImpl(new SPCookieStore(this)));            //使用sp保持cookie，如果cookie不过期，则一直有效
		builder.cookieJar(new CookieJarImpl(new DBCookieStore(this)));              //使用数据库保持cookie，如果cookie不过期，则一直有效
		//builder.cookieJar(new CookieJarImpl(new MemoryCookieStore()));            //使用内存保持cookie，app退出后，cookie消失

		//https相关设置，以下几种方案根据需要自己设置
		//方法一：信任所有证书,不安全有风险
		HttpsUtils.SSLParams sslParams1 = HttpsUtils.getSslSocketFactory();
		//方法二：自定义信任规则，校验服务端证书
		HttpsUtils.SSLParams sslParams2 = HttpsUtils.getSslSocketFactory(new SafeTrustManager());
		//方法三：使用预埋证书，校验服务端证书（自签名证书）
		//HttpsUtils.SSLParams sslParams3 = HttpsUtils.getSslSocketFactory(getAssets().open("srca.cer"));
		//方法四：使用bks证书和密码管理客户端证书（双向认证），使用预埋证书，校验服务端证书（自签名证书）
		//HttpsUtils.SSLParams sslParams4 = HttpsUtils.getSslSocketFactory(getAssets().open("xxx.bks"), "123456", getAssets().open("yyy.cer"));
		builder.sslSocketFactory(sslParams1.sSLSocketFactory, sslParams1.trustManager);
		//配置https的域名匹配规则，详细看demo的初始化介绍，不需要就不要加入，使用不当会导致https握手失败
		builder.hostnameVerifier(new SafeHostnameVerifier());

		// 其他统一的配置
		// 详细说明看GitHub文档：https://github.com/jeasonlzy/
		OkGo.getInstance().init(this)                           //必须调用初始化
				.setOkHttpClient(builder.build())               //建议设置OkHttpClient，不设置会使用默认的
				.setCacheMode(CacheMode.NO_CACHE)               //全局统一缓存模式，默认不使用缓存，可以不传
				.setCacheTime(CacheEntity.CACHE_NEVER_EXPIRE)   //全局统一缓存时间，默认永不过期，可以不传
				.setRetryCount(3);                              //全局统一超时重连次数，默认为三次，那么最差的情况会请求4次(一次原始请求，三次重连请求)，不需要可以设置为0
		//                .addCommonHeaders(headers)                      //全局公共头
		//                .addCommonParams(params);                       //全局公共参数
	}

	/**
	 * 这里只是我谁便写的认证规则，具体每个业务是否需要验证，以及验证规则是什么，请与服务端或者leader确定
	 * 这里只是我谁便写的认证规则，具体每个业务是否需要验证，以及验证规则是什么，请与服务端或者leader确定
	 * 这里只是我谁便写的认证规则，具体每个业务是否需要验证，以及验证规则是什么，请与服务端或者leader确定
	 * 重要的事情说三遍，以下代码不要直接使用
	 */
	private class SafeTrustManager implements X509TrustManager {
		@Override
		public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
		}

		@Override
		public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
			try {
				for (X509Certificate certificate : chain) {
					certificate.checkValidity(); //检查证书是否过期，签名是否通过等
				}
			} catch (Exception e) {
				throw new CertificateException(e);
			}
		}

		@Override
		public X509Certificate[] getAcceptedIssuers() {
			return new X509Certificate[0];
		}
	}

	/**
	 * 这里只是我谁便写的认证规则，具体每个业务是否需要验证，以及验证规则是什么，请与服务端或者leader确定
	 * 这里只是我谁便写的认证规则，具体每个业务是否需要验证，以及验证规则是什么，请与服务端或者leader确定
	 * 这里只是我谁便写的认证规则，具体每个业务是否需要验证，以及验证规则是什么，请与服务端或者leader确定
	 * 重要的事情说三遍，以下代码不要直接使用
	 */
	private class SafeHostnameVerifier implements HostnameVerifier {
		@Override
		public boolean verify(String hostname, SSLSession session) {
			//验证主机名是否匹配
			//return hostname.equals("server.jeasonlzy.com");
			return true;
		}
	}
}
